home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / wrlib / convolve.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-14  |  6.5 KB  |  311 lines

  1. /* 
  2.  *  Raster graphics library
  3.  * 
  4.  *  Copyright (c) 1997-2000 Alfredo K. Kojima
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *  
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *  
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <config.h>
  22.  
  23.  
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <X11/Xlib.h>
  28. #include "wraster.h"
  29.  
  30.  
  31. /*
  32.  *----------------------------------------------------------------------
  33.  * RBlurImage--
  34.  *     Apply 3x3 1 1 1 low pass, convolution mask to image.
  35.  *                1 2 1
  36.  *                1 1 1 /10
  37.  *----------------------------------------------------------------------
  38.  */
  39. int
  40. RBlurImage(RImage *image)
  41. {
  42.     register int x, y;
  43.     register int tmp;
  44.     unsigned char *ptr, *nptr;
  45.     unsigned char *pptr=NULL, *tmpp;
  46.     int ch = image->format == RRGBAFormat ? 4 : 3;
  47.  
  48.     pptr = malloc(image->width * ch);
  49.     if (!pptr) {
  50.     RErrorCode = RERR_NOMEMORY;
  51.     return False;
  52.     }
  53.  
  54. #define MASK(prev, cur, next, ch)\
  55.     (*(prev-ch) + *prev + *(prev+ch)\
  56.     +*(cur-ch) + 2 * *cur + *(cur+ch)\
  57.     +*(next-ch) + *next + *(next+ch)) / 10
  58.  
  59.     memcpy(pptr, image->data, image->width * ch);
  60.     
  61.     ptr = image->data;
  62.     nptr = ptr + image->width*ch;
  63.     tmpp = pptr;
  64.     
  65.     if (ch == 3) {
  66.     ptr+=3;
  67.     nptr+=3;
  68.     pptr+=3;
  69.  
  70.     for (y = 1; y < image->height-1; y++) {
  71.                 
  72.         for (x = 1; x < image->width-1; x++) {
  73.         tmp = *ptr;
  74.         *ptr = MASK(pptr, ptr, nptr, 3);
  75.         *pptr = tmp;
  76.         ptr++; nptr++; pptr++;
  77.  
  78.         tmp = *ptr;
  79.         *ptr = MASK(pptr, ptr, nptr, 3);
  80.         *pptr = tmp;
  81.         ptr++; nptr++; pptr++;
  82.  
  83.         tmp = *ptr;
  84.         *ptr = MASK(pptr, ptr, nptr, 3);
  85.         *pptr = tmp;
  86.         ptr++; nptr++; pptr++;
  87.         }
  88.         pptr = tmpp;
  89.         ptr+=6;
  90.         nptr+=6;
  91.         pptr+=6;
  92.     }
  93.     } else {
  94.     ptr+=4;
  95.     nptr+=4;
  96.     pptr+=4;
  97.  
  98.     for (y = 1; y < image->height-1; y++) {
  99.         for (x = 1; x < image->width-1; x++) {
  100.         tmp = *ptr;
  101.         *ptr = MASK(pptr, ptr, nptr, 4);
  102.         *pptr = tmp;
  103.         ptr++; nptr++; pptr++;
  104.  
  105.         tmp = *ptr;
  106.         *ptr = MASK(pptr, ptr, nptr, 4);
  107.         *pptr = tmp;
  108.         ptr++; nptr++; pptr++;
  109.  
  110.         tmp = *ptr;
  111.         *ptr = MASK(pptr, ptr, nptr, 4);
  112.         *pptr = tmp;
  113.         ptr++; nptr++; pptr++;
  114.         
  115.         tmp = *ptr;
  116.         *ptr = MASK(pptr, ptr, nptr, 4);
  117.         *pptr = tmp;
  118.         ptr++; nptr++; pptr++;
  119.         }
  120.         pptr = tmpp;
  121.         ptr+=8;
  122.         nptr+=8;
  123.         pptr+=8;
  124.     }
  125.     }
  126.     
  127.  
  128.     return True;
  129. }
  130.  
  131.  
  132. #if 0
  133. int
  134. REdgeDetectImage(RImage *image)
  135. {
  136.     register int x, y, d1, d2, d3, d4, rsum;
  137.     int w;
  138.     unsigned char *r, *g, *b, *a;
  139.     unsigned char *dr, *dg, *db, *da;
  140.     unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
  141.     RImage *image2;
  142.  
  143.  
  144.     image2 = RCloneImage(image);
  145.     
  146.     pr = alloca(image->width*sizeof(char));
  147.     if (!pr)
  148.       goto outofmem;
  149.  
  150.     pg = alloca(image->width*sizeof(char));
  151.     if (!pg)
  152.       goto outofmem;
  153.  
  154.     pb = alloca(image->width*sizeof(char));
  155.     if (!pb)
  156.       goto outofmem;
  157.  
  158.     pa = alloca(image->width*sizeof(char));
  159.     if (!pa)
  160.       goto outofmem;
  161.  
  162.     
  163.     r = image->data[0];
  164.     g = image->data[1];
  165.     b = image->data[2];
  166.     a = image->data[3];
  167.  
  168.     dr = image2->data[0];
  169.     dg = image2->data[1];
  170.     db = image2->data[2];
  171.     da = image2->data[3];
  172.  
  173.     
  174.     for (x=0; x<image->width; x++) {
  175.     *(dr++) = *(r++);
  176.     *(dg++) = *(g++);
  177.     *(db++) = *(b++);
  178.     }
  179.  
  180.     w = image->width;
  181.     
  182.     for (y=1; y<image->height-1; y++) {
  183.     dr[w-1] = r[w-1];
  184.     dg[w-1] = g[w-1];
  185.     db[w-1] = b[w-1];
  186.  
  187.     *(dr++) = *(r++);
  188.     *(dg++) = *(g++);
  189.     *(db++) = *(b++);
  190.     
  191.     for (x=1; x<image->width-1; x++) {
  192.         d1 = r[w+1]  - r[-w-1];
  193.         d2 = r[1]    - r[-1];  
  194.         d3 = r[-w+1] - r[w-1]; 
  195.         d4 = r[-w]   - r[w];
  196.  
  197.         rsum = d1 + d2 + d3;
  198.         if (rsum < 0) rsum = -rsum;
  199.         d1 = d1 - d2 - d4;         /* vertical gradient */
  200.         if (d1 < 0) d1 = -d1;
  201.         if (d1 > rsum) rsum = d1;
  202.         rsum /= 3;
  203.         
  204.         *(dr++) = rsum;
  205.         
  206.         d1 = g[w+1]  - g[-w-1];
  207.         d2 = g[1]    - g[-1];  
  208.         d3 = g[-w+1] - g[w-1]; 
  209.         d4 = g[-w]   - g[w];
  210.  
  211.         rsum = d1 + d2 + d3;
  212.         if (rsum < 0) rsum = -rsum;
  213.         d1 = d1 - d2 - d4;         /* vertical gradient */
  214.         if (d1 < 0) d1 = -d1;
  215.         if (d1 > rsum) rsum = d1;
  216.         rsum /= 3;
  217.         
  218.         *(dg++) = rsum;
  219.  
  220.         d1 = b[w+1]  - b[-w-1];
  221.         d2 = b[1]    - b[-1];  
  222.         d3 = b[-w+1] - b[w-1]; 
  223.         d4 = b[-w]   - b[w];
  224.  
  225.         rsum = d1 + d2 + d3;
  226.         if (rsum < 0) rsum = -rsum;
  227.         d1 = d1 - d2 - d4;         /* vertical gradient */
  228.         if (d1 < 0) d1 = -d1;
  229.         if (d1 > rsum) rsum = d1;
  230.         rsum /= 3;
  231.         
  232.         *(db++) = rsum;
  233.         
  234.         r++;
  235.         g++;
  236.         b++;
  237.     }
  238.         r++;
  239.         g++;
  240.         b++;
  241.  
  242.     dr++;
  243.     dg++;
  244.     db++;
  245.     }
  246.     {
  247.     r = image->data[0];
  248.     image2->data[0] = r;
  249.     g = image->data[1];
  250.     image2->data[1] = g;
  251.     b = image->data[2];
  252.     image2->data[2] = b;
  253.     RDestroyImage(image2);
  254.     }
  255.  
  256. #undef MASK
  257.     
  258.     return True;
  259. }
  260.  
  261.  
  262. int
  263. RSmoothImage(RImage *image)
  264. {
  265.     register int x, y;
  266.     register int v, w;
  267.     unsigned char *ptr;
  268.     int ch = image->format == RRGBAFormat;
  269.  
  270.     ptr = image->data;
  271.  
  272.  
  273.     w = image->width*ch;
  274.     for (y=0; y<image->height - 1; y++) {
  275.     for (x=0; x<image->width - 1; x++) {
  276.         v = *ptr + 2 * *(ptr + ch) + 2 * *(ptr + w) + *(ptr + w + ch);
  277.         *ptr = v/6;
  278.         v = *(ptr+1) + 2 * *(ptr+1 + ch) + 2 * *(ptr+1 + w) + *(ptr+1 + w + ch);
  279.         *(ptr+1) = v/6;
  280.         v = *ptr + 2 * *(ptr+2 + ch) + 2 * *(ptr+2 + w) + *(ptr+2 + w + ch);
  281.         *(ptr+2) = v/6;
  282.         
  283.         ptr+= ch;
  284.     }
  285.     /* last column */
  286.     v = 3 * *ptr + 3 * *(ptr + w);
  287.     *ptr = v/6;
  288.     v = 3 * *ptr + 3 * *(ptr+1 + w);
  289.     *(ptr+1) = v/6;
  290.     v = 3 * *ptr + 3 * *(ptr+2 + w);
  291.     *(ptr+2) = v/6;
  292.     
  293.     ptr+= ch;
  294.     }
  295.     
  296.     /* last line */
  297.     for (x=0; x<image->width - 1; x++) {
  298.     v = 3 * *ptr + 3 * *(ptr + ch);
  299.     *ptr = v/6;
  300.     v = 3 * *(ptr+1) + 3 * *(ptr+1 + ch);
  301.     *(ptr+1) = v/6;
  302.     v = 3 * *(ptr+2) + 3 * *(ptr+2 + ch);
  303.     *(ptr+2) = v/6;
  304.     
  305.     ptr+= ch;
  306.     }
  307.  
  308.     return True;
  309. }
  310. #endif
  311.